package com.cwx.mychat.login.authentication.phone;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cwx.mychat.entity.po.UserInfo;
import com.cwx.mychat.login.exception.CheckoutException;
import com.cwx.mychat.service.UserInfoService;
import com.cwx.mychat.utils.redis.RedisUtil;
import com.cwx.mychat.utils.stringUtils.StringUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * 作者： cwx
 * 时间： 2024/11/26 18:23
 * 版本： 1.0
 * 注释：
 */
@Slf4j
@Component
public class PhoneAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private PasswordEncoder passwordEncoder;


    public PhoneAuthenticationProvider(){super();}

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        try{
            //用户提交的用户名和密码
            String emailOrPhone = authentication.getName();
            String password = (String) authentication.getCredentials();
            if(emailOrPhone == null || "".equals(emailOrPhone)){
                throw new RuntimeException("用户不能为空");
            }
            //查询数据库，验证用户信息
            //从数据库中获取用户信息
            //判断数据是email还是phone
            UserInfo userInfo;
            if(StringUtil.isEmail(emailOrPhone)){
                //是email
                userInfo = userInfoService.getOne(new QueryWrapper<UserInfo>().lambda().eq(UserInfo::getEmail, emailOrPhone));
            } else if (StringUtil.isPhoneNumber(emailOrPhone)) {
                userInfo = userInfoService.getOne(new QueryWrapper<UserInfo>().lambda().eq(UserInfo::getPhone, emailOrPhone));
            }else{
                throw new RuntimeException("邮箱或手机号错误");
            }
            //判断用户是否存在
            if(userInfo == null){
                throw new UsernameNotFoundException("用户不存在");
            }
            //判断密码是否正确
            if(!passwordEncoder.matches(password, userInfo.getPassword())){
                throw new BadCredentialsException("用户名或密码错误");
            }
            PhoneAuthentication phoneAuthentication = new PhoneAuthentication();
            ObjectMapper objectMapper = new ObjectMapper();
            phoneAuthentication.setCurrentUser(objectMapper.convertValue(userInfo, UserInfo.class));
            phoneAuthentication.setAuthenticated(true);
            return phoneAuthentication;
        }catch (Exception e){
            log.error("认证出现异常", e);
            throw new CheckoutException(e.getMessage());
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.isAssignableFrom(PhoneAuthentication.class);
    }
}
